/*
 * parse.c
 *
 *  Created on: 02/feb/2014
 *      Author: massimo
 */

#include <msp430.h>
#include <string.h>
#include <stdlib.h>     /* atoi */
#include "init.h"

extern volatile unsigned char bufferRX[], Wptr, Rptr;
extern const char release[], relHw[];


///
/// analizza il messaggio che arrivato dalla seriale
///
void parseMessage(__statMsg *stM, __seq *seq){
	/// copio il buffer dentro la stringa da analizzare;
	unsigned char str[16], *tok;
	int cont = 0;

	/// deve essere una azione senza modifica dei puntatori di lettura e scrittura
	__bic_SR_register(GIE);
	if (Wptr > Rptr){
		strncpy(str, (char *)&bufferRX[Rptr], Wptr - Rptr - 1);
		str[Wptr - Rptr - 1] = 0;
		Rptr = Wptr;
	}
	else if(Wptr < Rptr){
		strncpy(str, (char *)&bufferRX[Rptr], BUFF_DIM - Rptr);
		strncpy(&str[BUFF_DIM - Rptr], (char *)&bufferRX, Wptr);
		/// end char
		str[BUFF_DIM - Rptr + Wptr] = 0;
		Rptr = Wptr;
		}
	__bis_SR_register(GIE);

	tok = strtok(str, " ,");
	while (tok != NULL && cont < 3){
		cont++;
		/// occorre confrontare i diversi token estratti
		tokCpm(cont, tok, stM, seq);
		tok = strtok (NULL, " ,");
	}
	if (cont >= 3)
		printf("\ncomando con troppi parametri\n");
	if(stM->stato == ERR_STATUS)
		printf("comando errato.\n\r");
}


///
/// confronta i token e capisce se sono errati
///
void tokCpm(int cont, char *tok, __statMsg *stM, __seq *seq){


	switch(cont){
	case 1:
		stM->stato = ERR_STATUS;
		/// controlla i 3 token possibili
		if(strcmp(tok, "tempo") == 0){
			/// tempo
			stM->cmd = TEMPO;
			stM->stato = STATO_OK;
			break;
		}
		if(strcmp(tok, "linea") == 0){
			/// imposta la linea di inzio della sequenza
			stM->cmd = IMP_LINEA;
			stM->stato = SET_LINEA;
			break;
		}
		if(strcmp(tok, "lineafin") == 0){
			/// imposta la linea di inzio della sequenza
			stM->cmd = IMP_LINEA_FINALE;
			stM->stato = SET_LINEA;
			break;
		}
		if(strcmp(tok, "avvio") == 0){
			/// avvio
			stM->cmd = AVVIO;
			stM->stato = STATO_OK;
			break;
		}
		if(strcmp(tok, "stop") == 0){
			/// stop
			stM->cmd = STOP;
			stM->stato = STATO_OK;
			break;
		}
		if(strcmp(tok, "ripeti") == 0){
			/// ripeti
			stM->rep = RIPETI;
			if(stM->stato != ON)
				/// solo se lo stato non e' on, lo mette in OFF
				stM->stato = OFF;
			break;
		}
		if(strcmp(tok, "linea?") == 0){
			/// chiede quale linea si sta eseguendo
			printf("\nlinea attiva n. %d\n\r", seq->stLine );
			stM->stato = LINEA_STATUS;
		}
		if(strcmp(tok, "release") == 0){
			printf("release sw: %s\n\r", release);
			printf("release hW: %s\n\r", relHw);
			stM->stato = RELEASE_STATUS;
		}
		if(strcmp(tok, "help") == 0){
			printf("help:\r\n");
			printf("tempo [minuti] e invio: imposta la durata dell'accenzione, in secondi\r\n");
			printf("linea [numero] e invio: imposta la linea da cui iniziare\r\n");
			printf("lineafin [numero] e invio: imposta la linea finale della sequenza\r\n");
			printf("ripeti e invio: ripete la sequenza dalla linea impostata all'ultima\r\n");
			printf("linea? e invio: restituisce la prima linea che verra' attivata\r\n");
			printf("release e invio: stampa la release software della scheda\r\n");
			printf("avvio e invio: avvia la sequenza\r\n");
			printf("stop e invio: ferma la sequenza\r\n");


			stM->stato = HELP_STATUS;

		}

	break;

	case 2:
		if (stM->cmd == 1){
			/// in tok c'e' il numero da convertire da carattere ad int

			stM->dato = atoi(tok);
			if (stM->dato != 0){
				/// se ci sono caratteri non validi il numero e' ridotto oppure e' 0
				stM->dato = impostaTemp(stM->dato);
				stM->stato = 0;
			}
			else
				stM->stato = ERR_STATUS;
		}
		if (stM->cmd == IMP_LINEA){
			/// imposta il numero di linea da eseguire
			seq->stLine = atoi(tok);
			if (seq->stLine < 1 || seq->stLine > MAX_LINE){
				printf("\n\rLinea al di fuori dell'intervallo permesso.\r\n");
				seq->stLine = 1;
				stM->stato = ERR_STATUS;
			}
		}
		if (stM->cmd == IMP_LINEA_FINALE){
			/// imposta il numero di linea da eseguire
			seq->endLine = atoi(tok);
			if (seq->stLine < 1 || seq->stLine > MAX_LINE){
				printf("\n\rLinea al di fuori dell'intervallo permesso.\r\n");
				seq->endLine = 20;
				stM->stato = ERR_STATUS;
			}
		}


	break;

	/// caso non riconosciuto: ERRORE
	default:
		stM->stato = ERR_STATUS;
	break;

	}

}


///
/// funzione per la printf
///
int fputc(int _c, register FILE *_fp){

	while(!(UCA1IFG&UCTXIFG));
	UCA1TXBUF = (unsigned char) _c;
	return((unsigned char)_c);
}


int fputs(const char *_ptr, register FILE *_fp){

  unsigned int i, len;

  len = strlen(_ptr);
  for(i=0 ; i<len ; i++){
    while(!(UCA1IFG&UCTXIFG));
    UCA1TXBUF = (unsigned char) _ptr[i];
  }
  return len;
}

